import { modelFilter } from './model-filter';
import { defaultProductId, defaultUpdateField, defaultUpdateFieldCollect } from '../constant';
import { CustomModel, CustomModelParam } from '../types';
import { IParamModelLiteData, IParamModelLiteParamData } from '@manycore/pages-vm-api';
import { unique } from './unique';

/**
 * 根据当前选中的模型，生成聚合参数
 * @param models
 */
export function transformParamModelToParameters(models: CustomModel[]) {
  // 找出所有中间件模型
  const allCenterModel = modelFilter(models, (m) => m.productId === defaultProductId, 5);
  const paramsMap = new Map<string, CustomModelParam[]>();

  defaultUpdateFieldCollect.forEach((key) => {
    paramsMap.set(
      key,
      allCenterModel
        .map((model) => {
          return model.getParam(key);
        })
        .filter((i): i is CustomModelParam => !!i)
    );
  });

  return defaultUpdateField.map((v) => {
    const fields = allCenterModel.length
      ? v.fields
          .filter((field) => {
            const currentParams = paramsMap.get(field);
            return currentParams && currentParams.some((p) => p.getVisible());
          })
          .map((field) => {
            // todo merge 参数
            let currentParams = (paramsMap.get(field) || []).filter((i) => i.getVisible());

            if (currentParams && !currentParams.length) {
              return undefined;
            }

            return transformParamToData(currentParams);
          })
          .filter((i): i is IParamModelLiteData => !!i)
      : [];
    return {
      ...v,
      fields,
    };
  });
}

/**
 * 将参数转换成自己的纯数据
 * @param params
 */
export function transformParamToData(params: CustomModelParam[]): IParamModelLiteData {
  const data = (params[0] as any).toJSON() as IParamModelLiteParamData;
  let { value, type, optionValues, recommendValues, name, max, min, step } = data;

  if (params.length > 1) {
    // merge 所有数据
    const values = unique(params.map((i) => i.getValue()));
    if (values.length > 1) {
      value = undefined!;
    }
  }

  // 最大值
  max = Math.min(
    ...unique(params.map((i) => i.getMax())).filter((i): i is number => typeof i === 'number' && !isNaN(i))
  );
  // 最小值
  min = Math.max(
    ...unique(params.map((i) => i.getMin())).filter((i): i is number => typeof i === 'number' && !isNaN(i))
  );

  if (!Number.isFinite(max)) {
    max = undefined;
  }
  if (!Number.isFinite(min)) {
    min = undefined;
  }
  if (step === null) {
    step = 1;
  }

  if (optionValues && optionValues.length) {
    optionValues = params.slice(1).reduce((previousValue, currentValue, currentIndex) => {
      const options = currentValue.getOptionValues() || [];
      return previousValue.filter((item) => {
        return (
          options.findIndex(function (option) {
            return item.value === option.value;
          }) !== -1
        );
      });
    }, optionValues);
  }

  if (recommendValues && recommendValues.length) {
    recommendValues = params.slice(1).reduce((previousValue, currentValue) => {
      const options = currentValue.getRecommendValues() || [];
      return previousValue.filter((item) => {
        return (
          options.findIndex(function (option) {
            return item.value === option.value;
          }) !== -1
        );
      });
    }, recommendValues);
  }

  if ((type === 'float' || type === 'int') && value !== undefined) {
    value = parseFloat(value).toString();
  }

  /*if (name === 'LZQ') {
        optionValues = recommendValues;
    }*/

  return {
    ...data,
    step,
    max,
    min,
    optionValues,
    value,
  };
}
